Skip to content

Feature/1797#123

Merged
Episkey-G merged 9 commits into
ucloud:masterfrom
markwei-ucloud:feature/1797
Jul 14, 2026
Merged

Feature/1797#123
Episkey-G merged 9 commits into
ucloud:masterfrom
markwei-ucloud:feature/1797

Conversation

@markwei-ucloud

Copy link
Copy Markdown
Contributor

Features:
添加uhadoop-api相关操作命令,包含以下命令:
Commands:

list List all UHadoop clusters

describe Describe a UHadoop cluster

create Create a UHadoop cluster

delete Delete a UHadoop cluster

add-node Add nodes to a UHadoop cluster

list-node-type List available node types for UHadoop

list-framework-app List UHadoop framework apps by use case

restart-service Restart/start/stop a UHadoop cluster service

upgrade-node Upgrade UHadoop node instance type

upgrade-disk Upgrade UHadoop node disk size
Fixes:

Comment thread products/uhadoop/product.yaml Outdated
@@ -0,0 +1,6 @@
name: uhadoop
owners:
- mark.wei@ucloud.cn

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

改为自己的github账号名称

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已处理

@Episkey-G Episkey-G left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

评审结论:Request changes

按《UCloud CLI 产品命令开发与接入规范》逐项核对,并把 PR 分支拉到本地实际跑了平台闸门。目录结构与大部分写法符合规范,机器闸门全绿,但有 2 类阻塞问题(功能缺陷 + 输出契约)与 owners 配置错误需要先解决。

已验证通过 ✅

检查 结果
go build ./... 通过
go run ./hack/check-product(规则 1-10) 全部通过
go test ./hack/snapshot -run 'TestProductGoldens/uhadoop|TestProductCompletionGoldens/uhadoop' 通过,golden 与命令树一致

目录布局、一 verb 一文件命名(add_node.goadd-node)、cli.NewServiceClient、危险操作 ctx.Confirm+--yes、长耗时 --async+Spollproducts.gen.go 由 gen-products 正确再生成——这些都符合规范,基础打得不错。👍

阻塞项 🔴

  1. owners 必须改为 GitHub 用户名 markwei-ucloud(product.yaml 行级评论已提,这里补充机制依据):owner-gate 用 github.event.pull_request.user.login 与 owners 逐项 EqualFold 比较(hack/owner-gate/main.go:201 + .github/workflows/pr-gate.yml:134),邮箱永远匹配不上。不改的话合并后本产品所有后续 PR 都会被判 non-owner 转平台审批,owner 自治与 auto-merge 对 uhadoop 永久失效。现有产品均为 GitHub 用户名(如 ufs 的 pearlinpan)。另请补首行注释,与其他产品 yaml 保持一致:# products/uhadoop/product.yaml — uhadoop 产品元数据(归属真源,owner 自治维护)
  2. list 强制 --zone,--all-region 整体不可用——实测复现,TEST.md 自己的示例命令现状直接报错,详见 list.go 行级评论。
  3. delete / restart-service 违反输出契约(规范 §2.5/§6/§11 禁止项)——PrintJSON/ctx.Err() 应改为 ctx.EmitResult/ctx.ProgressWriter(),详见行级评论。

建议项 🟡

  • create/add-node/upgrade-node/upgrade-disk 手写公共 flag,丢失 region/zone/project-id 补全,统一改 ctx.BindCommonParams(§8);
  • 全部 10 个子命令 MarkFlagRequired("region")/("zone"),profile 默认失效且与 "Optional." 描述自相矛盾,读类命令应去掉(§7);
  • describe.go 的无效 SetFlagValues(region) 删除;concern 归位:StateRunning→status.go、describeClusterForPoll→poll.go、sdkStr→用 sdk.String(§2.2/§2.3);rows.go 的 frameworkAppRow 死代码;
  • upgrade-* 的 node-role 补全含 client 与描述矛盾;
  • TEST.md 清理个人环境路径;测试结果表 14 项全部为 ⬜ 待测试,请真实跑完勾选后再合——这是本 PR 的验收证据;
  • create/list/describe/list-framework-app 四处绕开 SDK 类型走 InvokeAction 的 workaround(SDK 类型与 API 不符,注释已说明)可以接受,但请在 PR 描述显式声明,并给 ucloud-sdk-go 提修复 issue,SDK 修复后移除(§10 精神)。

提醒:凡涉及 flag required 状态、默认值或补全候选的调整,改完记得按 §2.4 重刷本产品两份 golden(WRITE_CMDTREE_GOLDEN=1 / WRITE_COMPLETION_GOLDEN=1),随同一 PR 提交。

command.SetFlagValues(cmd, "id-only", "true", "false")

cmd.MarkFlagRequired("region")
cmd.MarkFlagRequired("zone")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 阻塞:list 强制 --zone 后基本不可用,本 PR 的 TEST.md §1.3 示例即可复现:

$ ucloud uhadoop list --region cn-bj2
Error: required flag(s) "zone" not set

ListUHadoopInstance 按 region 列集群本不需要 zone;全仓也没有其他产品的 list 把 zone 设为 required(对照 uhost list:region/zone 均 Optional 且走 profile 默认)。请去掉 MarkFlagRequired("zone")(region 同理,见 create.go 处的整体评论),并重刷 cmdtree.golden。

return nil, err
}
for _, region := range regions {
_req := *req

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 阻塞:--all-region 模式整体不可用,两个原因:

  1. region/zone 被标 required,uhadoop list --all-region 直接报 required flag(s) "region", "zone" not set(实测);
  2. 即使凑齐参数,这里 _req := *req 浅拷贝保留了用户传入的 Zone 指针,fan-out 到每个 region 的请求都带着同一个 zone(拿着 cn-bj2-02 去查上海),其他地域基本查不出结果。

fan-out 前应把 _req.Zone 置空(或复制时显式清掉),并解除 all-region 与 required region/zone 的冲突。

return fmt.Errorf("[%d] %s", resp.RetCode, resp.Message)
}
fmt.Fprintf(ctx.Err(), "Cluster %s deleted\n", id)
ctx.PrintJSON(resp)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 输出契约违规(规范 §2.5/§6/§11 禁止项):写命令的结构化结果必须走 ctx.EmitResult(cli.OpResultRow{...}),人读文案走 ctx.ProgressWriter()。当前 fmt.Fprintf(ctx.Err(), ...) + ctx.PrintJSON(resp) 的问题:table 模式下也会把原始 SDK 响应整坨 JSON 打到 stdout;--output json 时结构又与其他命令的 OpResultRow 不一致,脚本无法统一解析。

同时建议与本产品其余 8 个命令保持一致,改回 Run + ctx.HandleError(RunE 返回裸 error 绕开了平台统一错误上报格式)。参考本 PR 内 create/add-node 的收尾写法,或 examples/product_onboarding/delete.go

return fmt.Errorf("[%d] %s", resp.RetCode, resp.Message)
}
fmt.Fprintf(ctx.Err(), "Service %s %s on cluster %s, state: %s\n", *req.ServiceName, action, *req.InstanceId, resp.State)
ctx.PrintJSON(resp)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 同 delete.go 的输出契约问题:去掉 ctx.PrintJSON(resp),人读文案改走 ctx.ProgressWriter(),收尾 ctx.EmitResult(cli.OpResultRow{ResourceID: *req.InstanceId, Action: action, Status: resp.State}),错误处理改 Run + ctx.HandleError

ctx.BindRegion(cmd, req)
ctx.BindZone(cmd, req)
ctx.BindProjectID(cmd, req)
req.InstanceId = cmd.Flags().String("instance-id", "", "Required. Cluster instance ID")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 描述写 "Required." 但没有 cmd.MarkFlagRequired("instance-id")(service-name 同),只靠 Run 里的手工校验:help 不标必填、报错时机也更晚,与本产品其他命令不一致。规范 §7 要求必填 flag 用 MarkFlagRequired 且描述以 Required. 开头,二者同时满足。改完按 §2.4 重刷 cmdtree.golden(required 状态入 golden)。

cmd.Flags().SortFlags = false
ctx.BindRegion(cmd, req)
ctx.BindZone(cmd, req)
command.SetFlagValues(cmd, "region", ctx.RegionList()...)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 这行是无效调用,请删除:BindRegion 已自动注册 region 的动态补全(规范 §8:「Region/Zone/Project 的补全由 Bind* 自动注册,产品无需手动调用任何 provider」),cobra 不允许对同一 flag 重复注册,这行被静默吞掉——completion.golden 里 describe 的 region 仍是 dynamic 可证。

"github.com/ucloud/ucloud-cli/pkg/command"
)

const StateRunning = "Running"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 concern 文件归位(规范 §2.2/§2.3):本文件是 describe verb 文件,但塞进了三个横切关注点——

  1. StateRunning 域状态常量 → status.go(可顺手改小写,包内使用无需导出);
  2. describeClusterForPoll 轮询闭包 → poll.go(describe.go 被 verb 占用时的规定去处,§2.2 命名冲突规则);
  3. sdkStrsdk.String 的重复实现(list.go 已 import sdk "github.com/ucloud/ucloud-sdk-go/ucloud"),统一用 sdk.String 后删除。

}

// frameworkAppRow is the row for ListUHadoopFrameworkAppByUseCase output.
type frameworkAppRow struct {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 frameworkAppRow 是死代码——list_framework_app.go 实际用的是它自己文件里定义的 frameworkRow(多一个 Versions 字段)。请删掉这个,并把 frameworkRow 挪进本文件(行结构体统一归 rows.go,规范 §2.2)。

yes = flags.BoolP("yes", "y", false, "Do not prompt for confirmation")
async = flags.Bool("async", false, "Optional. Do not wait for upgrade to complete")
flags.StringSliceVar(&nodeNames, "node-name", nil, "Node names, required when NodeRole != master")
command.SetFlagValues(cmd, "node-role", "master", "core", "task", "client")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 补全候选含 client,但 flag 描述(和 TEST.md)都只说 master|core|task——二者必有一错;若 API 不支持升级 client 节点,补全会诱导用户输入非法值,疑似从 add-node 复制多带了。upgrade_disk.go:60 同。修正后按 §2.4 重刷 completion.golden。

Comment thread products/uhadoop/TEST.md Outdated

# 3. 切换 Go 版本
g use 1.25.12
alias go=/Users/user/.g/go/bin/go

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 个人环境信息(g use 1.25.12alias go=/Users/user/.g/go/bin/go,下文 GOROOT 同)不应入库,请改成一般性环境要求(如「Go ≥ 1.25」)。

另外文末「测试结果」表 14 项全部为 ⬜ 待测试,其中 §1.3 的两条 list 示例现状必失败(见 list.go 评论)——请在合并前真实跑完并勾选结果,这份清单是本 PR 的验收证据。

@Episkey-G Episkey-G merged commit 306215f into ucloud:master Jul 14, 2026
20 of 24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants